package com.gzq.common_core.session;

import android.annotation.SuppressLint;

import androidx.annotation.NonNull;
import androidx.core.util.Preconditions;

import java.util.HashSet;
import java.util.Set;

public class SessionManager {
    private static volatile SessionManager instance;
    private ISession session;
    private final Set<SessionStateChangedListener> mSessionStateChangedListeners = new HashSet<>();
    private ISessionUser mUserInfo;
    private ISessionUserToken mUserTokenInfo;

    public static SessionManager instance() {
        if (instance == null) {
            synchronized (SessionManager.class) {
                if (instance == null) {
                    instance = new SessionManager();
                }
            }
        }
        return instance;
    }

    public void init() {
        session = new MmkvSession();
    }

    public void init(ISession session) {
        this.session = session;
    }

    @SuppressLint("RestrictedApi")
    public void setUserInfo(ISessionUser sessionUser) {
        Preconditions.checkNotNull(session, "Please init SessionManager");
        session.setUser(sessionUser);
        mUserInfo = sessionUser;
        notifyUserInfoChanged();
    }

    @SuppressLint("RestrictedApi")
    public <U extends ISessionUser> U getUserInfo() {
        if (mUserInfo != null) return (U) mUserInfo;
        Preconditions.checkNotNull(session, "Please init SessionManager");
        return (U) session.getUser();
    }

    @SuppressLint("RestrictedApi")
    public void setUserTokenInfo(ISessionUserToken sessionUserToken) {
        Preconditions.checkNotNull(session, "Please init SessionManager");
        session.setUserToken(sessionUserToken);
        mUserTokenInfo = sessionUserToken;
        notifyTokenChanged();
    }

    @SuppressLint("RestrictedApi")
    public <T extends ISessionUserToken> T getUserTokenInfo() {
        if (mUserTokenInfo != null) return (T) mUserTokenInfo;
        Preconditions.checkNotNull(session, "Please init SessionManager");
        return (T) session.getUserToken();
    }

    @SuppressLint("RestrictedApi")
    public void clear() {
        mUserInfo = null;
        mUserTokenInfo = null;
        Preconditions.checkNotNull(session, "Please init SessionManager");
        session.clear();
        notifyUserInfoCleared();
    }

    /**
     * 添加Session状态改变通知，在不用时候记得移除掉，避免内存泄漏
     */
    public void addSessionStateChangedListener(@NonNull SessionStateChangedListener listener) {
        mSessionStateChangedListeners.add(listener);
    }

    /**
     * 移除Session状态改变通知
     */
    public void removeSessionStateChangedListener(@NonNull SessionStateChangedListener listener) {
        mSessionStateChangedListeners.remove(listener);
    }

    protected void notifyUserInfoChanged() {
        for (SessionStateChangedListener listener : mSessionStateChangedListeners) {
            listener.onUserInfoChanged(this);
        }
    }

    protected void notifyTokenChanged() {
        for (SessionStateChangedListener listener : mSessionStateChangedListeners) {
            listener.onTokenInfoChanged(this);
        }
    }

    protected void notifyUserInfoCleared() {
        for (SessionStateChangedListener listener : mSessionStateChangedListeners) {
            listener.onUserInfoCleared(this);
        }
    }
}
